#include "Scene.h"
#include "GI.h"
#include <algorithm>

namespace RayTracePro
{
	class GeometryKdTreeEvaluator
	{
	public:
		static const float IntersectTime;
		static const float TraversalTime;
		static const float EmptyNodeBounus;
		static const int ElementsPerNode = 2;
	};

	const float GeometryKdTreeEvaluator::IntersectTime = 80.0f;
	const float GeometryKdTreeEvaluator::TraversalTime = 1.0f;
	const float GeometryKdTreeEvaluator::EmptyNodeBounus = 0.3f;

	Scene::~Scene()
	{
		if (globalPhotonMap)
			delete globalPhotonMap;
	}

	void Scene::PrepareRendering(int maxDepth)
	{
		Array<BBox, true> bboxes;
		BBox nodeBBox;
		bboxes.SetSize(geometries.Count());
		for (int i = 0; i<geometries.Count(); i++)
		{
			geometries[i]->ComputeBBox(bboxes[i]);
		}
		/*printf("%f %f %f - %f %f %f\n", bboxes[0].xMin,bboxes[0].yMin,bboxes[0].zMin,
			bboxes[0].xMax,bboxes[0].yMax,bboxes[0].zMax);*/
		kdTree.Elements.Clear();
		kdTree.Nodes.Clear();
		kdTree.Bounds.Init();
		BBoxEdge * edges = new BBoxEdge[geometries.Count()*2];
		int * geomLeft = new int[geometries.Count()];
		int * geomRight = new int[geometries.Count()*maxDepth];
		for (int i = 0; i<geometries.Count(); i++)
			geomLeft[i] = i;
		ConstructKdTree<Geometry*, GeometryKdTreeEvaluator>(kdTree, geometries.Buffer(), 0, bboxes, 
			edges, geomLeft, geometries.Count(), geomLeft, geomRight, maxDepth, 0);
		delete [] geomLeft;
		delete [] geomRight;
		delete [] edges;

		if (system->EnableGI)
			PrecomputeGI();
	}
}